<?php

namespace Service\Http;

use ReflectionClass;
use ReflectionException;
use Service\Http\Exception\RestException;
use Service\AjaxModel\AjaxResponse;

class Route
{
    private $method;
    private $path;
    private $callback;

    private static $routes = [];

    public function __construct(string $method, string $path, array $callback)
    {
        $this->method = $method;
        $this->path = $path;
        $this->callback = $callback;
    }

    public static function get($path, $callback)
    {
        self::register(new Route('GET', $path, $callback));
    }

    public static function post($path, $callback)
    {
        self::register(new Route('POST', $path, $callback));
    }

    /**
     * @param Request $request
     * @return AjaxResponse
     * @throws RestException
     */
    public static function handle(Request $request): AjaxResponse
    {
        require_once 'api.php';
        $target = null;
        foreach (Route::$routes as $route) {
            if ($route->method === $request->getMethod() && $route->path === $request->getPath()) {
                $target = $route;
            }
        }
        if (is_null($target)) {
            throw new RestException('Route Not Found', 404);
        }
        $class = $target->callback[0];
        $method_name = $target->callback[1];
        try {
            $class = new ReflectionClass($class);
            $class_obj = $class->newInstance();
            $method = $class->getMethod($method_name);
            $result = $method->invoke($class_obj, $request);
            if ($result instanceof AjaxResponse) {
                return $result;
            }
            return AjaxResponse::success($result);
        } catch (ReflectionException $e) {
            throw new RestException('Route Class Not Found');
        }
    }

    private static function register(Route $route)
    {
        array_push(Route::$routes, $route);
    }

}

